package cn.lili.modules.kit.plugin.alipay;

import cn.hutool.json.JSONUtil;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.event.TransactionCommitSendMQEvent;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.utils.SnowFlake;
import cn.lili.exchange.AmqpExchangeProperties;
import cn.lili.modules.member.client.VipClient;
import cn.lili.modules.member.client.VipConfigClient;
import cn.lili.modules.order.trade.client.TradeClient;
import cn.lili.modules.payment.entity.dos.CombinePaymentLog;
import cn.lili.modules.payment.entity.dos.PaymentCallbackLog;
import cn.lili.modules.payment.entity.dos.PaymentLog;
import cn.lili.modules.payment.entity.dto.PayParam;
import cn.lili.modules.payment.entity.dto.PaymentCallback;
import cn.lili.modules.payment.entity.dto.PaymentWakeupParam;
import cn.lili.modules.payment.entity.enums.PaymentSceneEnums;
import cn.lili.modules.payment.service.CombinePaymentLogService;
import cn.lili.modules.payment.service.IPaymentCallbackLogService;
import cn.lili.modules.payment.service.PaymentLogService;
import cn.lili.modules.payment.service.SupplierAuditService;
import cn.lili.modules.system.client.SettingClient;
import cn.lili.modules.system.entity.dos.LiVipConfig;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.UrbanSubstationAuditSetting;
import cn.lili.modules.system.entity.dto.payment.AlipayPaymentSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.routing.PaymentRoutingKey;
import cn.lili.util.AmqpSender;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

@Component
@Slf4j
public class AliPayPluginNewManage {
    @Resource
    private SettingClient settingClient;
    @Resource
    private PaymentLogService paymentLogService;
    @Resource
    private ApplicationEventPublisher applicationEventPublisher;
    @Resource
    private AmqpExchangeProperties amqpExchangeProperties;
    @Resource
    private CombinePaymentLogService combinePaymentLogService;
    @Resource
    private TradeClient tradeClient;

    @Resource
    private IPaymentCallbackLogService paymentCallbackLogService;

    /**
     * H5微信支付配置
     *
     * @return
     */
    public AlipayPaymentSetting alipayPaymentSetting() {
        Setting setting = settingClient.get(SettingEnum.ALIPAY_PAYMENT.name());
        if (setting != null) {
            return JSONUtil.toBean(setting.getSettingValue(), AlipayPaymentSetting.class);
        }
        throw new ServiceException(ResultCode.ALIPAY_NOT_SETTING);
    }

    /**
     * 普通订单发起支付参数
     *
     * @param paymentWakeupParam 支付唤醒参数
     */
    public JSONObject publicPay(PaymentWakeupParam paymentWakeupParam) {
        PayParam payParam = paymentWakeupParam.getPayParam();

        JSONObject bizContent = new JSONObject();
        //商户订单号，商家自定义，保持唯一性
        bizContent.put("out_trade_no", SnowFlake.getIdStr());
        //支付金额，最小值0.01元
        bizContent.put("total_amount", payParam.getTotalAmount());
        //订单标题，不可使用特殊符号
        bizContent.put("subject", payParam.getTitle());
        bizContent.put("product_code", "QUICK_WAP_WAY");

        //商户自定义参数
        JSONObject passbackParams = new JSONObject();
        passbackParams.put("isCombine",paymentWakeupParam.getIsCombine());
        bizContent.put("passback_params",passbackParams.toJSONString());

        //支付日志对象
        PaymentLog paymentLog = paymentWakeupParam.getPaymentLog();
        paymentLog.setOutTradeNo(bizContent.get("out_trade_no").toString());

        return bizContent;
    }

    /**
     * 合并订单支付
     * */
    public JSONObject mergePublicPay(PaymentWakeupParam paymentWakeupParam) {
        PayParam payParam = paymentWakeupParam.getPayParam();

        JSONObject bizContent = new JSONObject();
        //商户订单号，商家自定义，保持唯一性
        bizContent.put("out_trade_no", paymentWakeupParam.getCombinePaymentLog().getCombineOutTradeNo());
        //支付金额，最小值0.01元
        bizContent.put("total_amount", payParam.getTotalAmount());
        //订单标题，不可使用特殊符号
        bizContent.put("subject", payParam.getTitle());
        bizContent.put("product_code", "QUICK_WAP_WAY");

        //商户自定义参数
        JSONObject passbackParams = new JSONObject();
        passbackParams.put("isCombine",paymentWakeupParam.getIsCombine());
        bizContent.put("passback_params",passbackParams.toJSONString());
        return bizContent;
    }

    /**
     * 普通订单支付回调处理
     * @param map 支付宝反馈信息
     * */
    @Transactional
    public void publicNotify(Map<String, String> map){
        PaymentLog paymentLog = paymentLogService.getPaymentLogByOutTradeNo(map.get("out_trade_no"));
        if(paymentLog!=null&&paymentLog.getIsPay()){
            return;
        }
        assert paymentLog != null;

        if(Double.parseDouble(map.get("total_amount")) != paymentLog.getPrice()){
            log.info("Double.parseDouble(map.get(total_amount))" + Double.parseDouble(map.get("total_amount")));
            log.info("paymentLog.getPrice() = " + paymentLog.getPrice());
            log.info("支付宝普通订单---校验金额失败");
            return;
        }
        log.info("支付宝普通订单---校验金额成功");

        //写入主动查询结果
        paymentLog.setPaymentResponseSource(JSONUtil.toJsonStr(map));

        String paymentResult = map.get("trade_status");
        //支付成功则写入
        if (paymentResult.equals("TRADE_SUCCESS")) {
            paymentLog.setTransactionId(map.get("trade_no"));
            paymentLog.setOutTradeNo(map.get("out_trade_no"));
            paymentLog.setPrice(Double.parseDouble(map.get("total_amount")));
            paymentLog.setIsPay(true);
            //标记已检查
            paymentLog.setIsCheck(true);
        }
        //支付中则先返回
        else if (paymentResult.equals("USERPAYING")) {
            //标记需要再次查询
            paymentLog.setIsCheck(false);
            paymentLog.setPaymentResponseSource("交易中，等待回传");

        } else if (paymentResult.equals("CLOSED")) {
            //标记已校验
            paymentLog.setIsCheck(true);
        } else {
            paymentLog.setIsCheck(false);
        }
        paymentLogService.updateById(paymentLog);

        // 支付状态为TRUE才进行通知
        if (paymentLog.getIsPay().equals(true)) {
            PaymentCallback paymentCallback = PaymentCallback.builder().paymentLog(paymentLog).isCombine(false).build();

            try {
                //保存支付回调入参数据
                PaymentCallbackLog paymentCallbackLog = new PaymentCallbackLog();
                paymentCallbackLog.setOutTradeNo(paymentCallback.getPaymentLog().getOutTradeNo());
                paymentCallbackLog.setMethodName("AliPayPluginNewManage.publicNotify");
                paymentCallbackLog.setPaycallbackObj(JSONObject.toJSONString(paymentCallback));
                paymentCallbackLogService.save(paymentCallbackLog);
            } catch (Exception e) {
                log.info("保存支付回调入参数据 异常,catch异常,不影响正常支付回调业务处理", e);
            }
            log.info("支付宝支付场景1：{}", paymentLog.getPaymentScene());
            if (paymentLog.getPaymentScene().equals(PaymentSceneEnums.RECHARGE.name())) {
                log.info("支付宝进入充值回调1");
                applicationEventPublisher.publishEvent(TransactionCommitSendMQEvent.builder().source("普通支付回调业务").exchange(amqpExchangeProperties.getPayment()).routingKey(PaymentRoutingKey.PAYMENT_CALLBACK).message(paymentCallback).build());
            }else {
                tradeClient.paymentCallback(paymentCallback);
            }
            //applicationEventPublisher.publishEvent(TransactionCommitSendMQEvent.builder().source("普通支付回调业务").exchange(amqpExchangeProperties.getPayment()).routingKey(PaymentRoutingKey.PAYMENT_CALLBACK).message(paymentCallback).build());

        }
    }

    /**
     * 合并订单支付回调处理
     * */
    @Transactional
    public void mergePublicNotify(Map<String, String> map){
        String outTradeNo = map.get("out_trade_no");
        CombinePaymentLog combinePaymentLog = combinePaymentLogService.getCombinePaymentLogByCombineOutTradeNo(outTradeNo);
        if(combinePaymentLog!=null&&combinePaymentLog.getIsCheck()){
            return;
        }
        if(Double.parseDouble(map.get("total_amount")) != combinePaymentLog.getPrice()){
            log.info("Double.parseDouble(map.get(total_amount))" + Double.parseDouble(map.get("total_amount")));
            log.info("combinePaymentLog.getPrice() = " + combinePaymentLog.getPrice());
            log.info("支付宝合并订单---校验金额失败");
            return;
        }
        log.info("支付宝合并订单---校验金额成功");

        //写入主动查询结果
        combinePaymentLog.setPaymentResponseSource(JSONUtil.toJsonStr(map));
        combinePaymentLog.setIsCheck(true);
        combinePaymentLogService.updateById(combinePaymentLog);

        //获取子单支付日志
        List<PaymentLog> paymentLogs = paymentLogService.getPaymentLogByCombineOutTradeNo(combinePaymentLog.getCombineOutTradeNo());
        for (PaymentLog paymentLog : paymentLogs) {
            //如果子单支付日志的交易状态为成功
            paymentLog.setIsCheck(true);
            paymentLog.setIsPay(true);
            paymentLog.setTransactionId(map.get("trade_no"));
            paymentLog.setOutTradeNo(map.get("trade_no"));
            paymentLogService.updateById(paymentLog);
        }

        // 支付状态为TRUE才进行通知
        if (paymentLogs.get(0).getIsPay().equals(true)) {
            PaymentCallback paymentCallback = PaymentCallback.builder().paymentLogs(paymentLogs).combinePaymentLog(combinePaymentLog).isCombine(true).build();

            try {
                //保存支付回调入参数据
                PaymentCallbackLog paymentCallbackLog = new PaymentCallbackLog();
                paymentCallbackLog.setOutTradeNo(paymentCallback.getPaymentLog().getOutTradeNo());
                paymentCallbackLog.setMethodName("AliPayPluginNewManage.mergePublicNotify");
                paymentCallbackLog.setPaycallbackObj(JSONObject.toJSONString(paymentCallback));
                paymentCallbackLogService.save(paymentCallbackLog);
            } catch (Exception e) {
                log.info("保存支付回调入参数据 异常,catch异常,不影响正常支付回调业务处理", e);
            }
            log.info("支付宝支付场景2：{}", paymentLogs.get(0).getPaymentScene());
            if (paymentLogs.get(0).getPaymentScene().equals(PaymentSceneEnums.RECHARGE.name())) {
                log.info("支付宝进入充值回调2");
                applicationEventPublisher.publishEvent(TransactionCommitSendMQEvent.builder().source("合单支付回调业务").exchange(amqpExchangeProperties.getPayment()).routingKey(PaymentRoutingKey.PAYMENT_CALLBACK).message(paymentCallback).build());
            }else {
                tradeClient.paymentCallback(paymentCallback);
            }
            //applicationEventPublisher.publishEvent(TransactionCommitSendMQEvent.builder().source("合单支付回调业务").exchange(amqpExchangeProperties.getPayment()).routingKey(PaymentRoutingKey.PAYMENT_CALLBACK).message(paymentCallback).build());
        }
    }
}
